﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JAAF.UI
{
    /// <summary>
    /// Defines the scope of an element of tha state of a <see cref="UIProcess"/>.
    /// </summary>
    public enum StateElementScopeEnum
    {
        /// <summary>
        /// The element is visible only in the scope of the process that declared it and it is not inherited
        /// by the processes started under this process
        /// </summary>
        Private = 0,

        /// <summary>
        /// The element is shared with all the child processes started by this process.
        /// In fact the same value is referenced so when a change is made by any of the
        /// processes sharing this element, the change is visible to all of them.
        /// </summary>
        Shared = 1,

        /// <summary>
        /// The element is copied to an child process started by this process. However no link is maintained
        /// between the state element of this process and the element copied to the child process.
        /// </summary>
        Copied = 3
    }


    /// <summary>
    /// Defines the acces level for a <see cref="StateElement"/> (read/write, read only, write only etc).
    /// </summary>
    [Flags]
    public enum StateElementAccessLevelEnum
    {
        /// <summary>
        /// Makes the state element invisible to the data binding mechanism.
        /// </summary>
        None = 0,

        /// <summary>
        /// Provides read access to the element.
        /// </summary>
        Read = 1,

        /// <summary>
        /// Provides write access to the element.
        /// </summary>
        Write = 2,

        /// <summary>
        /// Provides full access to the element (Read and Write combined).
        /// </summary>
        Full = 3
    }


    /// <summary>
    /// This class encapsulates a <see cref="UIProcess">user interface process</see> element
    /// </summary>
    public class StateElement
    {
        #region Instance Data

        private string m_sName;

        private object m_oValue;

        private StateElementScopeEnum m_eScope;

        private StateElementAccessLevelEnum m_eAccessLevel;

        #endregion


        #region Events

        public delegate void ElementChangedEventHandler(StateElement _oElement, object _oOldValue);

        /// <summary>
        /// An event fired whenever an element of the <see cref="UIProcessState"/>
        /// is modified.
        /// </summary>
        public event ElementChangedEventHandler ElementChanged;

        #endregion


        #region Initialization

        internal StateElement(string _sName, object _oValue, StateElementScopeEnum _eScope, StateElementAccessLevelEnum _eAccessLevel)
        {
            m_sName = _sName;
            m_oValue = _oValue;
            m_eScope = _eScope;
            m_eAccessLevel = _eAccessLevel;
        }

        internal StateElement(StateElement _oCopyFrom)
        {
            m_sName = _oCopyFrom.Name;
            m_oValue = _oCopyFrom.Value;
            m_eScope = _oCopyFrom.Scope;
        }

        #endregion


        #region Properties

        public string Name
        {
            get
            { return m_sName; }
        }

        public object Value
        {
            get
            { return m_oValue; }

            set
            {
                if (this.ElementChanged == null)
                {
                    m_oValue = value;
                    return;
                }

                object oOldValue = m_oValue;
                m_oValue = value;
                this.ElementChanged(this, oOldValue);
            }
        }

        public StateElementScopeEnum Scope
        {
            get
            { return m_eScope; }
        }

        public StateElementAccessLevelEnum AccessLevel
        {
            get
            {
                return m_eAccessLevel;
            }
        }

        #endregion

    }

}
